home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Applications
/
Fixation 1.3
/
fastmap.cpp
< prev
next >
Wrap
Text File
|
1996-01-28
|
14KB
|
451 lines
// fastmap.cpp
// lots of fun assumtions ;-j
#include <stdio.h>
#include <stdlib.h>
#include "error.h"
//#include "Utilities.h"
#include "fastmap.h"
extern GWorldPtr boff;
// gworld must have bits locked
Fastmap::Fastmap( GWorldPtr gw, Boolean isMasked, short index, short hsize, short vsize )
{
PixMapHandle pmh = GetGWorldPixMap(gw); verify(pmh);
long *src, *dst;
src = (long *) GetPixBaseAddr(pmh); verify(src);
StripAddress(src);
masked = isMasked;
width = hsize;
if (width & 3) Debugger();
if (width == 0) {
width = (**pmh).bounds.right;
if (width & 3) Debugger();
if (masked)
width /= 2;
}
height = (**pmh).bounds.bottom;
if (vsize)
height = vsize;
long dataSize = (long) height * width;
if (masked)
dataSize *= 2; // need room for mask, which is mixed in
bits = (long *) NewPtr(dataSize); verify(bits);
// now we copy the picture from the gworld to our memory
long srcrb, soffset, loopoffset;
int rowlongs, loop;
long startx, endx;
dst = bits;
srcrb = (**pmh).rowBytes & 0x3fff;
startx = index * width;
endx = startx + width;
// set up offsets
soffset = startx;
src = (long *) ((long) src + soffset);
rowlongs = (endx - startx) >> 2;
// prepare for loop
loop = height;
loopoffset = srcrb - (rowlongs << 2);
// copy the pix
short nnn;
if (!masked)
while (loop-- > 0) {
for (nnn = 0; nnn < rowlongs; nnn++)
*dst++ = *src++;
// dst = (long *) (((long) dst) + loopoffset);
src = (long *) (((long) src) + loopoffset);
}
else {
long val, msk;
while (loop-- > 0) {
for (nnn = 0; nnn < rowlongs; nnn++) {
val = *src++;
// we make mask ourselves -- all whitespace is not mask
msk = 0;
if ((val & 0xFF000000) == 0) msk = 0xFF000000;
if ((val & 0x00FF0000) == 0) msk |= 0x00FF0000;
if ((val & 0x0000FF00) == 0) msk |= 0x0000FF00;
if ((val & 0x000000FF) == 0) msk |= 0x000000FF;
val |= msk; // change those zeroes to FF's
msk = msk ^ 0xFFFFFFFF; // flip mask, chump
*dst++ = val;
*dst++ = msk;
}
src = (long *) ((long) src + loopoffset);
}
}
}
void
Fastmap::Draw8by8Mask(GWorldPtr destworld, Rect *r)
{
PixMapPtr dstpm;
long *src, *dst, dest;
long dstrb, dstrbm4;
short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
if (r->left < 0 || r->top < 0 || r->right > winwidth || r->bottom > winheight)
return; // avoid writing over someone else's memory
src = bits;
dstpm = *destworld->portPixMap;
dest = (long) dstpm->baseAddr;
dstrb = dstpm->rowBytes & 0x3fff;
dstrbm4 = dstrb - 4;
dest += r->left;
dest += r->top * dstrb;
dst = (long *) dest;
// copy the pix
short nnn = height;
long tmp, msk, val;
while (nnn--) {
val = *src++;
tmp = *dst;
msk = *src++;
tmp |= msk;
tmp &= val;
*dst++ = tmp;
val = *src++;
tmp = *dst;
msk = *src++;
tmp |= msk;
tmp &= val;
*dst = tmp;
dst = (long *) ((long) dst + dstrbm4);
}
}
void
Fastmap::DrawMask(GWorldPtr destworld, Rect *r)
{
// PixMapPtr dstpm;
PixMapHandle pmh = GetGWorldPixMap(destworld);
register long *src, *dst;
long dest;
long dstrb;
short loop, copyLongs, srcDelta, leftStub;
short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
if (r->right < 0 || r->bottom < 0 || r->left >= winwidth || r->top >= winheight)
return; // avoid writing over someone else's memory
verify(r->right - r->left == width && r->bottom - r->top == height);
src = bits;
dest = (long) GetPixBaseAddr(pmh); verify(dest); StripAddress((void *) dest);
dstrb = (**pmh).rowBytes & 0x3fff;
dest += r->left;
dest += r->top * dstrb;
dst = (long *) dest;
loop = height;
copyLongs = width >> 2;
srcDelta = 0;
if (r->top < 0) { // runs off top of screen
short offs = -(r->top);
src = (long *) ((long) src + ((offs * width) << 1)); // offset source
dst = (long *) ((long) dst + offs * dstrb); // offset dest
loop -= offs;
}
if (r->bottom > winheight) { // runs off bottom of screen
loop -= r->bottom - winheight;
}
if (r->left < 0) { // runs off top of screen
short offs = -(r->left);
// square up
leftStub = offs & 3;
if (leftStub) offs += (4 - leftStub);
offs -= 4; // somehow this doesn't crash it
src = (long *) ((long) src + (offs << 1)); // offset source
dst = (long *) ((long) dst + offs); // offset dest
copyLongs -= offs >> 2;
srcDelta += offs;
}
if (r->right > winwidth) { // runs off right of screen
// we're going to let it run over for now, assume gworld has more rowbytes than should
short offs = r->right - winwidth;
// square up
offs -= offs & 3;
copyLongs -= offs >> 2;
srcDelta += offs;
}
if (copyLongs <= 0) return; // nuttin' to copy
// copy the pix
register long tmp, msk, val;
long dstDelta;
dstDelta = dstrb - (copyLongs << 2);
srcDelta <<= 1;
/* if (leftStub) {
// okay, we have to patch up the left column
// this sux, but we only rarely have to do it, and it shouldn't be too slow
// this will eventually be made moot
short myLoop = loop;
long *oldDest = dst, *oldSrc = src;
while (loop--) {
val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
dst = (long *) ((long) dst + dstDelta);
src = (long *) ((long) src + srcDelta);
}
dst = oldDest; src = oldSrc;
}*/
while (loop--) {
switch (copyLongs) {
case 24: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 23: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 22: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 21: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 20: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 19: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 18: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 17: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 16: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 15: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 14: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 13: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 12: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 11: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 10: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 9: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 8: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 7: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 6: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 5: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 4: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 3: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 2: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 1: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
case 0: break;
// default: DebugPrint(srcRect->right - srcRect->left); verify(false);
}
dst = (long *) ((long) dst + dstDelta);
src = (long *) ((long) src + srcDelta);
}
}
void
Fastmap::Draw(GWorldPtr destworld, Rect *r)
{
PixMapPtr dstpm;
PixMapHandle pmh = destworld->portPixMap;
register long *src, *dst;
long dest;
long dstrb;
short loop, copyLongs, srcDelta, leftStub;
short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
if (r->right < 0 || r->bottom < 0 || r->left >= winwidth || r->top >= winheight)
return; // avoid writing over someone else's memory
verify(r->right - r->left == width && r->bottom - r->top == height);
src = bits;
dstpm = *destworld->portPixMap;
dest = (long) GetPixBaseAddr(pmh); verify(dest); StripAddress((void *) dest);
dstrb = dstpm->rowBytes & 0x3fff;
dest += r->left;
dest += r->top * dstrb;
dst = (long *) dest;
loop = height;
copyLongs = width >> 2;
srcDelta = 0;
if (r->top < 0) { // runs off top of screen
short offs = -(r->top);
src = (long *) ((long) src + ((offs * width) << 1)); // offset source
dst = (long *) ((long) dst + offs * dstrb); // offset dest
loop -= offs;
}
if (r->bottom > winheight) { // runs off bottom of screen
loop -= r->bottom - winheight;
}
if (r->left < 0) { // runs off top of screen
short offs = -(r->left);
// square up
leftStub = offs & 3;
if (leftStub) offs += (4 - leftStub);
offs -= 4; // somehow this doesn't crash it
src = (long *) ((long) src + (offs << 1)); // offset source
dst = (long *) ((long) dst + offs); // offset dest
copyLongs -= offs >> 2;
srcDelta += offs;
}
if (r->right > winwidth) { // runs off right of screen
// we're going to let it run over for now, assume gworld has more rowbytes than should
short offs = r->right - winwidth;
// square up
offs -= offs & 3;
copyLongs -= offs >> 2;
srcDelta += offs;
}
if (copyLongs <= 0) return; // nuttin' to copy
// copy the pix
long dstDelta;
dstDelta = dstrb - (copyLongs << 2);
srcDelta <<= 1;
while (loop--) {
switch (copyLongs) {
case 24: *dst++ = *src++;
case 23: *dst++ = *src++;
case 22: *dst++ = *src++;
case 21: *dst++ = *src++;
case 20: *dst++ = *src++;
case 19: *dst++ = *src++;
case 18: *dst++ = *src++;
case 17: *dst++ = *src++;
case 16: *dst++ = *src++;
case 15: *dst++ = *src++;
case 14: *dst++ = *src++;
case 13: *dst++ = *src++;
case 12: *dst++ = *src++;
case 11: *dst++ = *src++;
case 10: *dst++ = *src++;
case 9: *dst++ = *src++;
case 8: *dst++ = *src++;
case 7: *dst++ = *src++;
case 6: *dst++ = *src++;
case 5: *dst++ = *src++;
case 4: *dst++ = *src++;
case 3: *dst++ = *src++;
case 2: *dst++ = *src++;
case 1: *dst++ = *src++;
case 0: break;
// default: DebugPrint(srcRect->right - srcRect->left); verify(false);
}
dst = (long *) ((long) dst + dstDelta);
src = (long *) ((long) src + srcDelta);
}
}
void
Fastmap::Draw8by8(GWorldPtr destworld, Rect *r)
{
if (masked) {
Draw8by8Mask(destworld, r);
return;
}
PixMapPtr dstpm;
PixMapHandle pmh;
long *src, *dst, dest;
long dstrb, dstrbm4;
short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
if (r->left < 0 || r->top < 0 || r->right > winwidth || r->bottom > winheight)
return; // avoid writing over someone else's memory
src = bits;
dstpm = *destworld->portPixMap;
dest = (long) dstpm->baseAddr;
dstrb = dstpm->rowBytes & 0x3fff;
dstrbm4 = dstrb - 4;
dest += r->left;
dest += r->top * dstrb;
dst = (long *) dest;
// copy the pix
*dst++ = *src++; *dst = *src++;
dst = (long *) ((long) dst + dstrbm4);
*dst++ = *src++; *dst = *src++;
dst = (long *) ((long) dst + dstrbm4);
*dst++ = *src++; *dst = *src++;
dst = (long *) ((long) dst + dstrbm4);
*dst++ = *src++; *dst = *src++;
dst = (long *) ((long) dst + dstrbm4);
*dst++ = *src++; *dst = *src++;
dst = (long *) ((long) dst + dstrbm4);
*dst++ = *src++; *dst = *src++;
dst = (long *) ((long) dst + dstrbm4);
*dst++ = *src++; *dst = *src++;
dst = (long *) ((long) dst + dstrbm4);
*dst++ = *src++; *dst = *src;
}
//extern GDHandle maindev;
//extern WindowPtr myWindow;
void LoadFastmaps(short baseID, short num, frameData *frameCounts, Rect *blockrect, Fastmap **bpix, short maxFrames)
{
short nnn;
Rect r;
PicHandle p;
verify(bpix);
verify(boff);
SetGWorld(boff, nil); // our scratch space
for (nnn = 0; nnn < num; nnn++) {
p = GetPicture(nnn + baseID);
if (!p)
verify(false); // forget this one
r = (**p).picFrame;
OffsetRect(&r, -r.left, -r.top);
verify(frameCounts[nnn].frames);
verify(r.right % frameCounts[nnn].frames == 0); // reasonably safe check of frames
blockrect[nnn] = r;
blockrect[nnn].right /= frameCounts[nnn].frames;
verify((blockrect[nnn].right & 3) == 0); // must be long-aligned
// paint the picture into scratch
EraseRect(&r);
DrawPicture(p, &r);
ReleaseResource((Handle) p);
/*
verify(myWindow);
SetGWorld((GWorldPtr) myWindow, maindev);
CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(((CWindowPtr) myWindow)->portPixMap),
&r, &r, srcCopy, nil);
SetGWorld(boff, nil);
Debugger();
*/
for (short mmm = 0; mmm < frameCounts[nnn].frames; mmm++) {
// make fast map and copy pic in
bpix[nnn*maxFrames+mmm] = new Fastmap(boff, frameCounts[nnn].masked,
mmm, blockrect[nnn].right, blockrect[nnn].bottom);
verify(bpix[nnn*maxFrames+mmm]);
}
}
}